package com.godyao.config;

import com.godyao.handler.EntryPointUnauthorizedHandler2;
import com.godyao.handler.RequestAccessDeniedHandler;
import com.godyao.security.jwt.config.JwtAuthenticationSecurityConfig;
import com.godyao.security.jwt.filter.TokenAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @author godyao
 * @date 2022/3/16
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private JwtAuthenticationSecurityConfig jwtAuthenticationSecurityConfig;

    @Autowired
    private EntryPointUnauthorizedHandler2 entryPointUnauthorizedHandler;

    @Autowired
    private RequestAccessDeniedHandler requestAccessDeniedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .disable()
                // 应用登录过滤器的配置
                .apply(jwtAuthenticationSecurityConfig)
                .and()
                .authorizeRequests()
                .mvcMatchers("/login", "/refreshToken", "/test*", "/v1/*")
                .permitAll()
                .mvcMatchers("/hello").hasRole("ADMIN")
                .anyRequest()
                .authenticated()
                // 处理异常情况：认证失败和权限不足
                .and()
                .exceptionHandling()
                // 认证未通过的处理器
                .authenticationEntryPoint(this.entryPointUnauthorizedHandler)
                // 认证通过，但是权限不足
                .accessDeniedHandler(requestAccessDeniedHandler)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)
                // 关闭csrf
                .csrf().disable();


    }

    // 自定义的Jwt Token校验过滤器
    @Bean
    public TokenAuthenticationFilter authenticationTokenFilterBean() {
        return new TokenAuthenticationFilter();
    }

    /**
     * 加密算法
     *
     * @return
     */
    @Lazy
    @Bean
    public PasswordEncoder getPasswordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
}